﻿using System;
using System.ComponentModel;
using System.Windows;
using System.Windows.Markup;
using Creventive.Wpf.ShellFactory.Workspace.Primitives;

namespace Creventive.Wpf.ShellFactory.Workspace
{
    /// <summary>
    ///   Provides a standardized window for shells.
    /// </summary>
    [ContentProperty]
    public class ApplicationViewContainerWindow : Window
    {
        #region Static Fields/Constants

        /// <summary>
        /// Backing field for the Source dependency property
        /// </summary>
        public static readonly DependencyProperty SourceProperty = DependencyProperty.Register("Source", typeof(IApplicationViewSource), typeof(ApplicationViewContainerWindow), new FrameworkPropertyMetadata(null, FrameworkPropertyMetadataOptions.None, (s, e) => ((ApplicationViewContainerWindow)s).OnSourceChanged((IApplicationViewSource)e.OldValue, (IApplicationViewSource)e.NewValue)));

        #endregion

        private SingleViewWorkspace workspacePart;

        static ApplicationViewContainerWindow()
        {
            DefaultStyleKeyProperty.OverrideMetadata(typeof(ApplicationViewContainerWindow), new FrameworkPropertyMetadata(typeof(ApplicationViewContainerWindow)));
        }

        /// <summary>
        ///   Gets or sets the source.
        /// </summary>
        /// <value>The source.</value>
        [TypeConverter(typeof(ApplicationViewSourceConverter))]
        public IApplicationViewSource Source
        {
            get { return (IApplicationViewSource)this.GetValue(SourceProperty); }
            set { this.SetValue(SourceProperty, value); }
        }

        /// <summary>
        ///   Gets the view currently being displayed.
        /// </summary>
        /// <value>The view.</value>
        public ApplicationView View
        {
            get
            {
                if (this.workspacePart != null)
                {
                    var workspaceItem = this.workspacePart.ActiveWorkspaceItem;
                    if (workspaceItem != null)
                        return workspaceItem.ApplicationView;
                }
                return null;
            }
        }

        /// <summary>
        ///   Called when the source has changed.
        /// </summary>
        /// <param name = "oldValue">The old value.</param>
        /// <param name = "newValue">The new value.</param>
        protected virtual void OnSourceChanged(IApplicationViewSource oldValue, IApplicationViewSource newValue)
        {}

        /// <summary>
        ///   When overridden in a derived class, is invoked whenever application code or internal processes call <see cref = "M:System.Windows.FrameworkElement.ApplyTemplate" />.
        /// </summary>
        public override void OnApplyTemplate()
        {
            base.OnApplyTemplate();
            this.workspacePart = this.Template.FindName("PART_Workspace", this) as SingleViewWorkspace;
        }

        /// <summary>
        ///   Raises the <see cref = "E:System.Windows.Window.Closing" /> event.
        /// </summary>
        /// <param name = "e">A <see cref = "T:System.ComponentModel.CancelEventArgs" /> that contains the event data.</param>
        protected override void OnClosing(CancelEventArgs e)
        {
            if (this.workspacePart != null)
            {
                if (!this.workspacePart.CloseAll(ApplicationViewClosingMode.QueryOnly))
                {
                    e.Cancel = true;
                    return;
                }
            }
            base.OnClosing(e);
            if (e.Cancel)
                return;
        }

        /// <summary>
        ///   Raises the <see cref = "E:System.Windows.Window.Closed" /> event.
        /// </summary>
        /// <param name = "e">An <see cref = "T:System.EventArgs" /> that contains the event data.</param>
        protected override void OnClosed(EventArgs e)
        {
            if (this.workspacePart != null)
                this.workspacePart.CloseAll(ApplicationViewClosingMode.NoQuery);
            base.OnClosed(e);
        }
    }
}